<template>
    <div class="dashboard">
        <header class="header">
            <div class="left">
                <button class="icon-btn lg" aria-label="down" @click="slideDownAndGoHome">
                    <!-- chevron-down without stem -->
                    <svg viewBox="0 0 24 24" width="28" height="28" aria-hidden="true"><path fill="currentColor" d="M6.7 8.7a1 1 0 0 1 1.4 0L12 12.6l3.9-3.9a1 1 0 1 1 1.4 1.4l-4.6 4.6a1 1 0 0 1-1.4 0L6.7 10.1a1 1 0 0 1 0-1.4z"/></svg>
                </button>
            </div>
            <div class="title">仪表盘</div>
            <div class="right">
                <!-- share icon at top-right -->
                <button class="icon-btn" aria-label="share" @click="noop">
                    <!-- share arrow to top-right inside a circle -->
                    <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
                        <path fill="currentColor" d="M12 2a10 10 0 1 0 .001 20.001A10 10 0 0 0 12 2zm2.95 6.05h-3.6a1 1 0 1 0 0 2h1.17l-4.56 4.56a1 1 0 0 0 1.42 1.42l4.56-4.56v1.17a1 1 0 1 0 2 0v-3.6a1 1 0 0 0-1-1z"/>
                    </svg>
                </button>
            </div>
        </header>

        <main class="content">
            <div class="stage" :style="{ transform: `translateY(${stageOffset}px)` }" ref="stageEl">
                <div class="study-top">
                    <div class="study-title">正在学习</div>
                    <button class="pill switch" @click="goToLibrary">换本词书</button>
                </div>
                <div class="study-wrap">
                    <section class="card studying">
                <div class="row">
                    <div class="book">
                        <div class="cover" :class="{ 'has-cover': hasCoverImage }" :style="progressCoverStyle">
                            <div class="cover-content" v-show="shouldShowCoverContent" :style="{ 
                                color: progressCoverMeta?.textColor || '#fff'
                            }">
                                <div class="cover-icon">{{ progressCoverMeta?.icon || '⚡' }}</div>
                                <div class="cover-text">
                                    <span v-for="(line, idx) in (progressCoverMeta?.lines || ['词书'])" :key="idx">{{ line }}</span>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="meta"></div>
                </div>

                <!-- info line between book and progress -->
                <div class="info-line">
                    <button type="button" class="cb" :class="{ checked: wordbookChecked }" @click="onCheckboxToggle">
                        <span class="tick">✔</span>
                    </button>
                    <span class="label">生词本</span>
                    <span class="num">{{ dashboardData.wordbook.wordCount || 0 }}</span>
                </div>

                <!-- progress moved below the info line -->
                <div class="progress-wrap below">
                    <div class="bar">
                        <div class="fill" :style="{ width: dashboardData.progress.progressPercent + '%' }"></div>
                    </div>
                    <div class="counts">
                        <span class="done">已学习 {{ dashboardData.progress.learnedWords || 0 }}</span>
                        <span class="total">总词数 {{ dashboardData.progress.totalWords || 0 }}</span>
                    </div>
                </div>
                </section>
                </div>

                <section class="section-title">我的数据</section>

                <section class="card stats">
                <div class="stats-head">
                    <div class="sec-title">概览</div>
                    <div class="chev">›</div>
                </div>
                <div class="overview grid">
                    <div class="cell">
                        <div class="cell-row">
                            <span class="i yellow">⚡</span>
                            <span class="lab">今日学习&复习</span>
                        </div>
                        <div class="val strong align-under">{{ dashboardData.statistics.todayTotalWords || 0 }} <span class="unit">词</span></div>
                    </div>
                    <div class="cell">
                        <div class="cell-row">
                            <span class="i coral">📈</span>
                            <span class="lab">累计学习</span>
                        </div>
                        <div class="val strong align-under">{{ dashboardData.statistics.totalLearnedWords || 0 }} <span class="unit">词</span></div>
                    </div>
                    <div class="cell">
                        <div class="cell-row">
                            <span class="i orange">⏱</span>
                            <span class="lab">今日总时长</span>
                        </div>
                        <div class="val strong align-under">{{ dashboardData.statistics.todayDuration || 0 }} <span class="unit">分钟</span></div>
                    </div>
                    <div class="cell">
                        <div class="cell-row">
                            <span class="i red">🕒</span>
                            <span class="lab">累计时长</span>
                        </div>
                        <div class="val strong align-under">{{ dashboardData.statistics.totalDuration || 0 }} <span class="unit">分钟</span></div>
                    </div>
                </div>
                </section>

                <!-- 可继续下滑扩展更多块，保证页面不限制尺寸 -->
                <section class="card placeholder">
                <div class="placeholder-title">更多内容占位</div>
                <p>向下滚动以展示更多数据模块……</p>
                </section>
                <section class="card placeholder">
                <div class="placeholder-title">更多内容占位</div>
                <p>向下滚动以展示更多数据模块……</p>
                </section>
                <section class="card placeholder">
                <div class="placeholder-title">更多内容占位</div>
                <p>向下滚动以展示更多数据模块……</p>
                </section>
            </div>
        </main>
    </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, onActivated, nextTick, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { fetchDashboard } from '@/utils/api.js'
import { generateWordbookCover } from '@/utils/coverPalette.js'

const router = useRouter()
const route = useRoute()
const wordbookChecked = ref(true)
const hasRoutedOnScroll = ref(false)
const lastScrollY = ref(0)
const stageOffset = ref(0) // 当前不再改动，保持 0 以保证可自然滚动
const stageEl = ref(null)
const reachedTop = ref(false)
const headerHeight = 64
const isLoading = ref(false)
const coverImageState = ref('idle') // idle | loading | success | error

// 仪表盘数据
const dashboardData = ref({
    wordbook: {
        id: null,
        name: '加载中...',
        coverUrl: '',
        wordCount: 0,
    },
    progress: {
        learnedWords: 0,
        totalWords: 0,
        progressPercent: 0,
    },
    statistics: {
        todayTotalWords: 0,
        todayDuration: 0,
        totalLearnedWords: 0,
        totalDuration: 0,
    },
})

// 计算封面图片相关属性
const hasCoverImage = computed(() => {
    const url = dashboardData.value.wordbook?.coverUrl
    // 检查 URL 是否有效（不为空、null、undefined 或空字符串，且必须是有效的 HTTP/HTTPS URL）
    if (!url || typeof url !== 'string') {
        console.log('封面 URL 检查: 不是字符串或为空', { url, wordbookName: dashboardData.value.wordbook?.name })
        return false
    }
    const trimmed = url.trim()
    if (trimmed === '' || 
        trimmed === 'null' || 
        trimmed === 'undefined' ||
        trimmed.startsWith('null') ||
        trimmed.startsWith('undefined')) {
        console.log('封面 URL 检查: 是空值或 null/undefined', { trimmed, wordbookName: dashboardData.value.wordbook?.name })
        return false
    }
    // 先检查是否以 http:// 或 https:// 开头（快速检查）
    const lowerTrimmed = trimmed.toLowerCase()
    if (!lowerTrimmed.startsWith('http://') && !lowerTrimmed.startsWith('https://')) {
        console.log('封面 URL 检查: 不是 HTTP/HTTPS URL，将显示生成封面', { trimmed, wordbookName: dashboardData.value.wordbook?.name, hasCoverImage: false })
        return false
    }
    // 验证是否为有效的 HTTP/HTTPS URL
    try {
        const urlObj = new URL(trimmed)
        const isValid = (urlObj.protocol === 'http:' || urlObj.protocol === 'https:') && 
                       urlObj.hostname.length > 0
        console.log('封面 URL 检查结果:', { 
            url: trimmed, 
            isValid, 
            protocol: urlObj.protocol, 
            hostname: urlObj.hostname, 
            wordbookName: dashboardData.value.wordbook?.name,
            willShowGeneratedCover: !isValid
        })
        return isValid
    } catch (e) {
        // 不是有效的 URL 格式，返回 false
        console.log('封面 URL 格式无效，将显示生成封面:', { url: trimmed, error: e.message, wordbookName: dashboardData.value.wordbook?.name })
        return false
    }
})

const coverStyle = computed(() => {
    const url = coverImageUrl.value
    if (coverImageState.value === 'success' && url) {
        console.log('使用封面图片 URL:', url)
        return {
            backgroundImage: `url(${url})`,
            backgroundSize: 'cover',
            backgroundPosition: 'center',
            backgroundRepeat: 'no-repeat',
        }
    }
    // 没有有效封面时，返回空对象，使用默认渐变背景
    console.log('使用默认封面样式（渐变背景）', { url, coverState: coverImageState.value })
    return {}
})

// 进度条区域的封面样式（根据词书名称生成）
const progressCoverMeta = computed(() => {
    try {
        const name = dashboardData.value.wordbook?.name || '词书'
        const meta = generateWordbookCover(name)
        // 确保始终有有效的值
        const result = {
            gradient: meta?.gradient || 'linear-gradient(140deg, #6366f1, #8b5cf6)',
            icon: meta?.icon || '⚡',
            textColor: meta?.textColor || '#fff',
            lines: (meta?.lines && meta.lines.length > 0) ? meta.lines : ['词书'],
        }
        console.log('封面元数据生成:', { name, result, hasCoverImage: hasCoverImage.value, willShowContent: !hasCoverImage.value })
        return result
    } catch (e) {
        console.error('生成封面元数据失败:', e)
        return {
            gradient: 'linear-gradient(140deg, #6366f1, #8b5cf6)',
            icon: '⚡',
            textColor: '#fff',
            lines: ['词书'],
        }
    }
})

// 辅助函数：验证 URL 是否有效（严格验证，确保无效 URL 绝对不会被使用）
function isValidImageUrl(url) {
    if (!url || typeof url !== 'string') {
        console.log('isValidImageUrl: 不是字符串或为空', { url })
        return false
    }
    const trimmed = url.trim()
    if (trimmed === '' || trimmed === 'null' || trimmed === 'undefined' ||
        trimmed.startsWith('null') || trimmed.startsWith('undefined')) {
        console.log('isValidImageUrl: 是空值或 null/undefined', { trimmed })
        return false
    }
    const lowerTrimmed = trimmed.toLowerCase()
    // 必须是以 http:// 或 https:// 开头的完整 URL
    if (!lowerTrimmed.startsWith('http://') && !lowerTrimmed.startsWith('https://')) {
        console.log('isValidImageUrl: 不是 HTTP/HTTPS URL', { trimmed })
        return false
    }
    try {
        const urlObj = new URL(trimmed)
        const isValid = (urlObj.protocol === 'http:' || urlObj.protocol === 'https:') && 
                       urlObj.hostname.length > 0
        console.log('isValidImageUrl: URL 解析结果', { trimmed, isValid, protocol: urlObj.protocol, hostname: urlObj.hostname })
        return isValid
    } catch (e) {
        console.log('isValidImageUrl: URL 解析失败', { trimmed, error: e.message })
        return false
    }
}

const coverImageUrl = computed(() => {
    const url = dashboardData.value.wordbook?.coverUrl
    const trimmed = typeof url === 'string' ? url.trim() : ''
    if (isValidImageUrl(trimmed)) {
        return trimmed
    }
    return null
})

watch(coverImageUrl, (url) => {
    if (!url) {
        coverImageState.value = 'error'
        return
    }
    coverImageState.value = 'loading'
    const img = new Image()
    img.onload = () => {
        coverImageState.value = 'success'
    }
    img.onerror = () => {
        coverImageState.value = 'error'
    }
    img.src = url
}, { immediate: true })

// 计算是否应该显示封面内容（只有当有有效封面图片时才隐藏）
const shouldShowCoverContent = computed(() => {
    const shouldShow = coverImageState.value !== 'success'
    console.log('是否显示封面内容:', { 
        coverState: coverImageState.value,
        coverUrl: coverImageUrl.value,
        shouldShow,
        wordbookName: dashboardData.value.wordbook?.name,
        coverMetaExists: !!progressCoverMeta.value
    })
    return shouldShow
})

const progressCoverStyle = computed(() => {
    const url = coverImageUrl.value
    if (coverImageState.value === 'success' && url) {
        console.log('使用封面图片 URL:', url)
        return {
            backgroundImage: `url(${url})`,
            backgroundSize: 'cover',
            backgroundPosition: 'center',
            backgroundRepeat: 'no-repeat',
        }
    }
    // 确保始终有渐变背景（无效 URL 时使用生成封面）
    const gradient = progressCoverMeta.value?.gradient || 'linear-gradient(140deg, #6366f1, #8b5cf6)'
    console.log('使用生成封面渐变:', { gradient, coverState: coverImageState.value, url })
    return {
        background: gradient,
    }
})

// 获取仪表盘数据
async function loadDashboard() {
    isLoading.value = true
    try {
        console.log('=== 开始获取仪表盘数据 ===')
        const data = await fetchDashboard()
        console.log('获取到的数据:', data)
        
        if (data) {
            // 重置封面图片加载状态，强制重新加载封面
            coverImageState.value = 'idle'
            coverImageUrl.value = ''
            
            dashboardData.value = {
                wordbook: {
                    id: data.wordbook?.id ?? null,
                    name: data.wordbook?.name || '未选择词书',
                    coverUrl: data.wordbook?.coverUrl || '',
                    wordCount: data.wordbook?.wordCount || 0,
                },
                progress: {
                    learnedWords: data.progress?.learnedWords || 0,
                    totalWords: data.progress?.totalWords || 0,
                    progressPercent: data.progress?.progressPercent || 0,
                },
                statistics: {
                    todayTotalWords: data.statistics?.todayTotalWords || 0,
                    todayDuration: data.statistics?.todayDuration || 0,
                    totalLearnedWords: data.statistics?.totalLearnedWords || 0,
                    totalDuration: data.statistics?.totalDuration || 0,
                },
            }
            console.log('更新后的仪表盘数据:', dashboardData.value)
            console.log('数据一致性检查:', {
                '当前词书已学习': dashboardData.value.progress.learnedWords,
                '累计学习': dashboardData.value.statistics.totalLearnedWords,
                '差异': dashboardData.value.progress.learnedWords - dashboardData.value.statistics.totalLearnedWords,
                '说明': '当前词书已学习数应该 <= 累计学习数（如果只学了一本词书，应该相等）'
            })
            
            // 封面图片会通过 watch(coverImageUrl) 自动加载，这里不需要手动调用
        } else {
            console.warn('获取到的数据为空')
        }
    } catch (error) {
        console.error('获取仪表盘数据失败:', error)
        console.error('错误详情:', error.message)
        // 保持默认值，显示加载中状态
    } finally {
        isLoading.value = false
    }
}

function slideDownAndGoHome() {
    const root = document.querySelector('.dashboard')
    if (!root) { router.push('/'); return }
    root.classList.add('leaving-down')
    // 给 body 临时上背景，避免动画期间露出纯白
    const originalBg = document.body.style.background
    document.body.style.background = '#f7f7f8'
    // 稍早切路由，避免空白停顿，但动画依旧顺滑
    setTimeout(() => {
        router.push('/')
        // 动画结束后恢复 body 背景
        setTimeout(() => { document.body.style.background = originalBg }, 500)
    }, 160)
}

function goToLibrary() {
    router.push({ name: 'library' })
}

function noop() {}

function onCheckboxToggle() {
    wordbookChecked.value = !wordbookChecked.value
    // 预留回调，可在此处接入真实业务
    onWordbookCheckboxClick()
}

function onWordbookCheckboxClick() {}

// 滚动超过页面一半，瞬间跳转首页
function handleWheelControlled(e) {
    if (hasRoutedOnScroll.value) return
    const delta = e.deltaY
    const step = Math.min(Math.abs(delta), 80)
    const atWindowTop = window.scrollY <= 0

    // 当在页面顶端且继续向上滚，则拦截默认滚动，改为拉出背景
    if (atWindowTop && delta < 0) {
        e.preventDefault()
        stageOffset.value = Math.min(window.innerHeight, stageOffset.value + step)
        if (stageOffset.value > window.innerHeight * 0.5) {
            hasRoutedOnScroll.value = true
            document.querySelector('.dashboard')?.classList.add('leaving-down')
            setTimeout(() => router.push('/'), 220)
        }
        return
    }

    // 若已经拉出一段背景，则在滚轮过程中用自定义位移，不让浏览器滚窗口
    if (stageOffset.value > 0) {
        e.preventDefault()
        if (delta > 0) {
            // 向下滚，收回背景
            stageOffset.value = Math.max(0, stageOffset.value - step)
        } else if (delta < 0) {
            // 继续向上滚，增大背景
            stageOffset.value = Math.min(window.innerHeight, stageOffset.value + step)
            if (stageOffset.value > window.innerHeight * 0.5) {
                hasRoutedOnScroll.value = true
                document.querySelector('.dashboard')?.classList.add('leaving-down')
                setTimeout(() => router.push('/'), 220)
            }
        }
    }
}

function getTopGapToHeader() {
    const el = stageEl.value?.querySelector('.study-top')
    if (!el) return 0
    const rect = el.getBoundingClientRect()
    return Math.max(0, rect.top - headerHeight - 8)
}

// 监听路由变化，当从LibraryPage跳转过来时重新加载数据
watch(() => route.name, async (newName, oldName) => {
    // 如果从library页面跳转到dashboard，重新加载数据
    if (newName === 'dashboard' && oldName === 'library') {
        console.log('从LibraryPage跳转到Dashboard，重新加载数据')
        await loadDashboard()
    }
}, { immediate: false })

// 当组件被激活时（使用keep-alive时），也重新加载数据
onActivated(async () => {
    // 如果是从library跳转过来的，重新加载数据
    if (route.name === 'dashboard') {
        await loadDashboard()
    }
})

onMounted(async () => {
    lastScrollY.value = window.scrollY
    await nextTick()
    window.addEventListener('wheel', handleWheelControlled, { passive: false })
    // 加载仪表盘数据
    await loadDashboard()
})

onBeforeUnmount(() => {
    window.removeEventListener('wheel', handleWheelControlled)
})
</script>

<style scoped>
.dashboard {
    min-height: 100vh;
    background: #f7f7f8;
    color: #111827;
}

.leaving-down { transform: translateY(100vh); opacity: 0; transition: transform .4s ease, opacity .4s ease; }

.header {
    position: sticky;
    top: 0;
    z-index: 10;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    height: 64px;
    padding: 0 16px;
    background: #fff;
    border-bottom: 1px solid #f0f0f2;
}
.header .title { text-align: center; font-size: 18px; font-weight: 600; }
.header .left { justify-self: start; }
.header .right { justify-self: end; display: flex; align-items: center; gap: 10px; }
.icon-btn.lg svg { width: 28px; height: 28px; }

.icon-btn {
    border: none;
    background: transparent;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    cursor: pointer;
}
.pill {
    height: 34px;
    padding: 0 16px;
    border: none;
    border-radius: 999px;
    background: rgba(253, 233, 221, 0.9);
    color: #ef6c00;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    writing-mode: horizontal-tb;
    font-weight: 600;
    min-width: 90px; /* 胶囊最小宽度，背景更大更显眼 */
}

.content { padding: 16px; max-width: 1120px; margin: 0 auto; }
.stage { will-change: transform; transition: transform .16s ease; }
.study-top { display: flex; align-items: center; justify-content: space-between; padding: 8px 6px 10px; }
.study-title { font-size: 22px; font-weight: 700; color: #1f2937; margin-left: 8px; }

.card {
    background: #fff;
    border-radius: 14px;
    border: 1px solid #f0f1f3;
    box-shadow: 0 1px 1px rgba(0,0,0,0.02);
}

.study-wrap { position: relative; }
.studying { padding: 18px; }
.studying { position: relative; }
.studying .row { display: flex; gap: 22px; align-items: flex-start; }
.study-wrap .pill.switch { position: absolute; right: 6px; top: -46px; }
.study-top .switch { position: static; }

.book { display: flex; gap: 16px; }
.cover {
    width: 120px;
    height: 160px;
    border-radius: 10px;
    background: linear-gradient(180deg, #5b3bff 0%, #3a2bb7 100%);
    position: relative;
    display: grid;
    place-items: center;
    color: #fff;
    overflow: hidden;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}
.cover.has-cover {
    background-size: cover !important;
    background-position: center !important;
    background-repeat: no-repeat !important;
}
.cover-content {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    padding: 12px 8px;
    box-sizing: border-box;
    position: relative;
    z-index: 1;
}
.cover-icon {
    font-size: 44px;
    line-height: 1;
    margin-top: 8px;
}
.cover-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 3px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    text-align: center;
    margin-bottom: 8px;
}
.cover-text span {
    display: block;
}

.slot.add {
    width: 88px;
    height: 120px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    border: 2px dashed #e6e7eb;
    color: #a0a3ab;
    font-size: 28px;
}

.meta { flex: 1; }
.line { display: flex; align-items: center; gap: 8px; font-size: 14px; color: #444; }
.check { color: #ef6c00; }
.label { color: #666; }
.num { color: #111827; font-weight: 600; }

.progress-wrap { margin-top: 20px; }
.progress-wrap.below { margin-top: 18px; }
.bar { height: 8px; background: #efefef; border-radius: 999px; overflow: hidden; }
.fill { height: 100%; background: #ff6a00; width: 0; transition: width 0.4s ease; border-radius: 999px; }
.counts { display: flex; justify-content: space-between; color: #8f939b; font-size: 14px; margin-top: 10px; }

.info-line { display: flex; align-items: center; gap: 8px; margin-top: 14px; margin-left: 4px; font-size: 15px; }
.info-line .label { color: #666; }
.info-line .label { font-size: 16px; }
.info-line .num { color: #111827; font-weight: 700; font-size: 18px; }

/* checkbox styles */
.cb { width: 22px; height: 22px; border-radius: 6px; border: 1.5px solid #e5e7eb; background: #fff; display: grid; place-items: center; cursor: pointer; padding: 0; }
.cb .tick { font-size: 14px; color: #ef6c00; line-height: 1; transform: translateY(-1px); opacity: 0; transition: opacity .15s ease; }
.cb.checked { border-color: #f4b78a; background: #fff7ed; }
.cb.checked .tick { opacity: 1; }

.section-title { margin: 18px 4px 12px; font-size: 20px; font-weight: 700; }

.stats { padding: 10px 24px 16px; }
.stats-head { display: flex; align-items: center; justify-content: space-between; padding: 6px 2px 12px; }
.sec-title { font-size: 16px; font-weight: 700; }
.chev { color: #9aa0a6; font-size: 20px; }
.overview.grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px 28px; }
.cell { display: flex; flex-direction: column; justify-content: center; }
.cell-row { display: inline-flex; align-items: center; gap: 10px; }
.i { width: 22px; height: 22px; display: grid; place-items: center; border-radius: 6px; font-size: 14px; }
.i.yellow { color: #ef6c00; }
.i.coral { color: #e53935; }
.i.orange { color: #fb8c00; }
.i.red { color: #d32f2f; }
.lab { color: #6b7280; font-size: 13px; }
.val { margin-top: 4px; font-size: 22px; color: #111827; font-weight: 800; }
.val.align-under { margin-left: calc(22px + 10px); }
.val.strong { font-weight: 800; font-size: 26px; }
.unit { color: #9aa0a6; font-weight: 500; font-size: 14px; }

@media (min-width: 920px) {
    .overview { grid-template-columns: repeat(4, 1fr); }
}

.placeholder { margin-top: 14px; padding: 18px; }
.placeholder-title { font-weight: 600; margin-bottom: 6px; }
</style>


